package article2.builder;

import java.util.EnumSet;
import java.util.Objects;
import java.util.Set;

/**
 * Builder 模式也适用于类层次结构
 * 使用平行层次结构的 builder 时，各自嵌套在相应的类中。抽象类有抽象的builder ，
 * 具体类有具体的 builder。假设用类层次根部的一个抽象类表示各式各样的比萨：
 * @author cctv
 */
public abstract class Pizza {

    /**
     * 配料
     * 火腿 蘑菇 洋葱 胡椒 香肠
     */
    public enum Topping{HAM,MUSHROOM,ONION,PEPPER,SAUSAGE}
    final Set<Topping> toppings;

    abstract static  class Builder<T extends  Builder<T>>{
        EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);
        public T addTopping(Topping topping){
            toppings.add(Objects.requireNonNull(topping));
            return self();
        }
        abstract Pizza build();

        protected abstract T self();
    }
    Pizza(Builder<?> builder){
        toppings = builder.toppings.clone();// see Item 50
    }

//    注意， Pizza.Builder的类型是泛型（generic type ），带有一个递归类型参数（recursive type parameter ），
//    详见第 30条。 它和抽象的 self 方法一样，允许在子类中适当地进行方法链接，
//    不需要转换类型 这个针对 Java 缺乏 self 型的解决方案，被称作模拟的 self型（ mulated-self-type ）


}
